package com.cskaoyan.javase.oop3._0abstract._3exercise;

import com.sun.org.apache.bcel.internal.classfile.Code;

/**
 * 公司正在开发一套员工管理系统，需要对公司内部存在的员工进行管理
 * 公司将员工分为三类，普通员工负责杂项工作，程序员负责技术开发，经理负责统筹规划
 * 普通员工包含3个属性：姓名、工号以及工资，行为是工作
 * 程序员包含3个属性：姓名、工号以及工资，行为是工作和加班（overtime work）
 * 经理包含4个属性：姓名、工号、工资以及奖金（bonus），行为是工作
 * 请使用所学的知识设计该员工系统
 * 要求类中提供必要的方法进行属性访问（description）
 *
 * 程序需要定义父类继承,实现成员的复用,那么父类是谁呢?
 *      1.将普通员工作为父类,在这个案例中,当前的场景下,是可以这么做的.
 *          但是从长远角度来说,这样不好.
 *          普通员工本身就存在它的对象,如果用它做父类,修改它,就会体现到所有子类中,这样不合适.
 *          其次,普通类中没有抽象方法,不能强制约束子类行为.而不论什么员工都是需要工作的
 *      2.综上,这里我们需要一个抽象的,不创建对象的,顶层父类:
 *          AbstractStaff
 *
 * 要求类中提供必要的方法进行属性访问（description）这里普通员工和程序员没有独有的属性
 * 这意味着它们两个类可以共用一个方法
 * 但是经理不行
 * 于是这个方法可以写在抽象类中,普通员工和程序员直接继承并使用,经理重写后再使用
 *
 * @since 11:18
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 创建对象并测试该案例
        AbstractStaff as;
        as = new NormalStaff("张三", 100, 10000);
        as.work();
        as.printStaff();
        as = new Coder("李四", 200, 50000);
        as.work();
        as.printStaff();
        /*
            程序员主动申请加班
            必须要做一次强转,需要instanceof判断
         */
        if (as instanceof Coder) {
            ((Coder) as).overtimeWork();
        }
        as = new Manager("王二", 300, 100000, 200000);
        as.work();
        as.printStaff();
    }
}

// 定义抽象父类
abstract class AbstractStaff {
    private String name;
    private int id;
    private double salary;

    public String getName() {
        return name;
    }

    public int getId() {
        return id;
    }

    public double getSalary() {
        return salary;
    }

    public AbstractStaff(String name, int id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    public AbstractStaff() {
    }

    // 打印员工的方法
    public void printStaff() {
        System.out.println("工号为:" + id + "的员工,他的名字是:" + name + ",他的工资是:" + salary);
    }

    // 定义抽象方法:工作,强制子类实现该方法
    public abstract void work();
}

// 定义普通子类
// 普通员工类
class NormalStaff extends AbstractStaff {
    @Override
    public void work() {
        System.out.println("我来完成杂项工作");
    }

    public NormalStaff(String name, int id, double salary) {
        super(name, id, salary);
    }

    public NormalStaff() {
    }
}

// 程序员类
class Coder extends AbstractStaff {
    @Override
    public void work() {
        System.out.println("我来完成技术开发工作");
    }

    public void overtimeWork() {
        System.out.println("996");
    }

    public Coder(String name, int id, double salary) {
        super(name, id, salary);
    }

    public Coder() {
    }
}

class Manager extends AbstractStaff {
    private double bonus;

    @Override
    public void work() {
        System.out.println("我来完成统筹规划工作");
    }

    public Manager(String name, int id, double salary, double bonus) {
        super(name, id, salary);
        this.bonus = bonus;
    }

    public Manager(double bonus) {
        this.bonus = bonus;
    }

    // 重写print方法

    @Override
    public void printStaff() {
        System.out.println("工号为:" + getId() + "的员工,他的名字是:" + getName() + ",他的工资是:" + (getSalary() + this.bonus));

    }
}